package com.xmall.auth.security.provider;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xmall.auth.entity.SysAccount;
import com.xmall.auth.service.remote.SysUserServiceFeign;
import com.xmall.auth.service.ISysAccountService;
import com.xmall.auth.utils.PasswordUtils;
import com.xmall.define.base.Result;
import com.xmall.define.base.ResultCode;
import com.xmall.auth.define.dict.AccountTypeEnum;
import com.xmall.define.dto.login.SysLoginInfo;
import com.xmall.define.dto.login.UserDto;
import com.xmall.exception.XmallException;
import com.xmall.security.SysPhonePasswordAuthenticationToken;
import org.springframework.beans.BeanUtils;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 用户登录校验
 */
@Component
public class SysPhonePasswordAuthenticationProvider implements AuthenticationProvider {

    @Resource
    private ISysAccountService sysAccountService;

    @Resource
    private SysUserServiceFeign sysUserServiceFeign;

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        SysPhonePasswordAuthenticationToken token = (SysPhonePasswordAuthenticationToken)authentication;

        // 查询用户
        QueryWrapper<SysAccount> query = new QueryWrapper<SysAccount>()
                .eq("type", AccountTypeEnum.PHONE.getType())
                .eq("account", token.getPrincipal());
        SysAccount sysAccount = sysAccountService.getOne(query);
        if(null == sysAccount){
            throw new XmallException(ResultCode.AUTH_LOGIN_ERROR);
        }

        // 验证密码
        if(!PasswordUtils.checkPassword((String) token.getCredentials(), sysAccount.getPassword())){
            throw new XmallException(ResultCode.AUTH_LOGIN_ERROR);
        }

        // 登录信息
        SysLoginInfo sysLoginInfo = new SysLoginInfo();
        BeanUtils.copyProperties(sysAccount, sysLoginInfo);

        // 查询权限信息
        Result<UserDto> result = sysUserServiceFeign.userPermission(sysLoginInfo.getUserId());
        if(null == result || !result.callSuccess()){
            throw new XmallException(ResultCode.AUTH_LOGIN_ERROR);
        }
        BeanUtils.copyProperties(result.getData(), sysLoginInfo);
        List<SimpleGrantedAuthority> authorities = sysLoginInfo.getPermissionArr().stream().map(permission -> new SimpleGrantedAuthority(permission)).collect(Collectors.toList());

        return new SysPhonePasswordAuthenticationToken(sysLoginInfo, sysLoginInfo.getAccount(), authorities);
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return SysPhonePasswordAuthenticationToken.class.isAssignableFrom(authentication);
    }
}
